package utils;

import com.github.javaparser.ParseException;
import com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.model.JavaClass;

import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static app.Config.SOURCE_CODE_BASE_DIR;

public class ParserUtil {

    private static JavaProjectBuilder builder;

    public static JavaProjectBuilder getBuilder() {
        if (builder == null) {
            builder = new JavaProjectBuilder();
        }
        return builder;
    }

    // 已添加文件到builder
    public static JavaClass getJavaClassByName(String fullyQualifiedName) throws ParseException {
        File file = getFileByClassName(fullyQualifiedName);
        if (file.exists()) {
            try {
                getBuilder().addSource(file);
            } catch (IOException e) {
                throw new ParseException("解析器添加文件失败！");
            }
            return getBuilder().getClassByName(fullyQualifiedName);
        } else {
            try {
                Class.forName(fullyQualifiedName);
                return getBuilder().getClassByName(fullyQualifiedName);
            } catch (ClassNotFoundException e) {
                throw new ParseException("文件未找到！");
            }
        }
    }

    public static File getFileByClassName(String fullyQualifiedName) {
        return new File(getAbsolutePathByName(fullyQualifiedName));
    }

    public static String getAbsolutePathByName(String fullyQualifiedName) {
        String file_dir = "";
        if (fullyQualifiedName.indexOf('.') > 0) {
            String class_name = fullyQualifiedName.substring(fullyQualifiedName.lastIndexOf('.') + 1);
            String package_name = fullyQualifiedName.substring(0, fullyQualifiedName.lastIndexOf('.')).replace('.', '/');
            file_dir = SOURCE_CODE_BASE_DIR + "/" + package_name + "/" + class_name + ".java";
        } else {
            file_dir = SOURCE_CODE_BASE_DIR + "/" + fullyQualifiedName + ".java";
        }
        return file_dir;
    }

    /**
     * [fix]: JavaClass 获取的源码 未初始化的参数会出现 "=;"（UserDao userDao=; ）的情况
     * [fix]: JavaClass 获取jdk库中的接口时会出现多个interface关键字
     * [unFix]: JavaClass 获取jdk库中的接口时泛型丢失
     */
    public static String getFixedCode(JavaClass cls) {
        String java_class_code = cls.getCodeBlock();
        //String prefix = java_class_code.substring(0, java_class_code.indexOf('{'));
        String body = java_class_code.substring(java_class_code.indexOf('{'));
        if (body.replaceAll("\\s*", "").equals("{}")) {
            return null;
        }
        Pattern pattern = Pattern.compile("\\s*=\\s*;");
        Matcher matcher = pattern.matcher(java_class_code);
        while (matcher.find()) {
            java_class_code = matcher.replaceAll(";");
            matcher = pattern.matcher(java_class_code);
        }
        java_class_code = java_class_code.replaceAll("interface\\s*interface", "interface");
        if (cls.isInterface()) {
            java_class_code = java_class_code.replaceAll("transient", "").replaceAll("volatile", "");
        }
        return java_class_code;
    }

}
